
//OS
#include <jxos_config.h>
#include "lib/ring_buff.h"
#include "lib/lib.h"
#include "kernel/jxos_task.h"
#include "kernel/jxos_event.h"
#include "kernel/jxos_msg.h"
#include "power_mgr_task.h"

#if ((JXOS_TASK_ENABLE == 1)&&(JXOS_SYS_SERVICE_DEBUG_PRINT_TASK_ENABLE == 1))
#if (JXOS_SYS_SERVICE_POWER_MGR_TASK_ENABLE == 1)
static uint8_t debug_print_keep_wake_mark;
#endif
static uint8_t print_buffer_space[PRINT_BUFF_LEN] = {0};
RINGBUFF_MGR print_buffer_mgr;

void (*sys_debug_print_task_hal_init_callback)(void) = 0;
uint8_t (*sys_debug_print_task_send_finish_check_callback)(void) = 0;	//1:send finish, 0:busy
void (*sys_debug_print_task_send_byte_callback)(uint8_t byte) = 0;

static void sys_debug_print_task(uint8_t task_id, void * parameter)
{
	uint8_t byte;
	if(sys_debug_print_task_send_finish_check_callback != 0){
		if((sys_debug_print_task_send_finish_check_callback() == 0)
		&&((ringbuff_check_used_space(&print_buffer_mgr) == 0))){
#if (JXOS_SYS_SERVICE_POWER_MGR_TASK_ENABLE == 1)
			sys_power_mgr_task_keep_wake_mark_reset(debug_print_keep_wake_mark);
#endif
		}
		if(sys_debug_print_task_send_finish_check_callback() == 1){
			if(sys_debug_print_task_send_byte_callback != 0){
				if(ringbuff_read_data(&print_buffer_mgr, 1, &byte) == 1){
					sys_debug_print_task_send_byte_callback(byte);
				}
			}
		}
	}
}

void sys_debug_print_task_init(void)
{
	RingBuff(&print_buffer_mgr, PRINT_BUFF_LEN, print_buffer_space);

	//HAL
	if(sys_debug_print_task_hal_init_callback != 0){
		sys_debug_print_task_hal_init_callback();
	}
	//BSP

	//OS
	jxos_task_create(sys_debug_print_task, "de_prt_t", 0);
#if (JXOS_SYS_SERVICE_POWER_MGR_TASK_ENABLE == 1)
	debug_print_keep_wake_mark = sys_power_mgr_task_keep_wake_mark_get_id();
#endif
	//LIB

	//SYS TASK
}


static void __putchar(uint8_t c, uint8_t is_blocked)
{
	if(!is_blocked){
		ringbuff_write_data(&print_buffer_mgr, 1, &c);
#if (JXOS_SYS_SERVICE_POWER_MGR_TASK_ENABLE == 1)
		sys_power_mgr_task_keep_wake_mark_set(debug_print_keep_wake_mark);
#endif
	}
	else{
		if((sys_debug_print_task_send_byte_callback != 0)
			&&(sys_debug_print_task_send_finish_check_callback != 0)){
			sys_debug_print_task_send_byte_callback(c);
			while(sys_debug_print_task_send_finish_check_callback() != 1);
		}
	}
}

static void __debug_print_itoa(uint8_t* string, uint8_t len, uint8_t is_blocked)
{
	len -= 1;
	while(1){
		__putchar(string[len], is_blocked);
		if(len == 0){
			break;
		}
		len--;
	}
}

/*********************************************************************************/
/*********************************************************************************/
void sys_debug_print_task_clr_buff(void)
{
	RingBuff(&print_buffer_mgr, PRINT_BUFF_LEN, print_buffer_space);
}

void sys_debug_print_task_print_str(char* str, uint8_t is_blocked)
{
	uint8_t i = 0;

	if(!is_blocked){
		while(str[i] != '\0'){
			i++;
		}
		ringbuff_write_data(&print_buffer_mgr, i, str);
#if (JXOS_SYS_SERVICE_POWER_MGR_TASK_ENABLE == 1)
		sys_power_mgr_task_keep_wake_mark_set(debug_print_keep_wake_mark);
#endif
	}
	else{
		while(*str != '\0'){
			if((sys_debug_print_task_send_byte_callback != 0)
				&&(sys_debug_print_task_send_finish_check_callback != 0)){
				sys_debug_print_task_send_byte_callback(*str);
				str++;
				while(sys_debug_print_task_send_finish_check_callback() != 1);
			}
		}
	}

}

void sys_debug_print_task_print_int(int32_t value, uint8_t is_blocked)
{
	int8_t string[8];
	uint8_t len;

	__itoa(string, &len, value, 10, 1);
	__debug_print_itoa(string, len, is_blocked);
}

void sys_debug_print_task_print_uint(uint32_t value, uint8_t is_blocked)
{
	int8_t string[8];
	uint8_t len;

	__itoa(string, &len, value, 10, 0);
	__debug_print_itoa(string, len, is_blocked);
}

void sys_debug_print_task_print_hex(uint32_t value, uint8_t is_blocked)
{
	int8_t string[8];
	uint8_t len;

	__itoa(string, &len, value, 16, 0);
	__debug_print_itoa(string, len, is_blocked);
}

void sys_debug_print_task_print_bin(uint32_t value, uint8_t is_blocked)
{
	int8_t string[8];
	uint8_t len;

	__itoa(string, &len, value, 2, 0);
	__debug_print_itoa(string, len, is_blocked);
}

void sys_debug_print_task_print_data_stream_in_hex(uint8_t* data_stream, uint8_t data_stream_len, uint8_t is_blocked)
{
	uint8_t i = 0;

    while(i < data_stream_len){
		sys_debug_print_task_print_hex(data_stream[i++], is_blocked);
		sys_debug_print_task_print_str(" ", is_blocked);
    }
}

#endif
